[Rust] Cloudflare WorkersでJSON形式の設定ファイルっぽいものを使う
Introduction
Cloudflare Workersは、Cloudflareが提供するFaaSです。
GoogleのV8 JavaScriptエンジンを基盤として構築されたサーバーレスプラットフォームで、
高速な起動とエッジネットワークによる低遅延な処理が特徴です。
JavaScriptまたはWasmのコードを実行することができるので、
WebAssemblyにコンパイルできるなら他の言語でも実装可能です。
設定ファイルみたいなものを使いたい
アプリの設定などは通常、kv形式のプロパティファイル、
yamlやjsonなどのファイルを使います。
普通のアプリであればそれらのファイルをバンドルして実行時にloadすればよいのですが、
Workersである程度複雑な形式のデータをプロパティファイルとして扱いたい場合、
Cloudflare Workers KVやDurable Objects、
その他外部のストレージサービスなどからデータを取得しなければいけません。
いちいちそういったものを使うのが面倒なので、
今回はRust(workers-rs)を使って、
ローカルにあるJsonファイルのデータをWorkersからアクセスできるようにします。
Environment
- MacBook Pro (13-inch, M1, 2020)
- OS : MacOS 13.5.2
- Rust : 1.75.0
- Node : v20.8.1
Cloudflareのアカウントは設定済みとします。
Setup
まずはwranglerでプロジェクトを作成します。
% npx wrangler generate workers-example https://github.com/cloudflare/workers-sdk/templates/experimental/worker-rust ・・・ % cd workers-example
devコマンドでローカルで起動すればOKです。
% npm run dev
publishコマンドでリモート環境にデプロイされます。
% npm run publish
Try
Workersでプロパティにアクセスする方法はいくつかあるので、
それらについて紹介します。
varsを使う
シンプルにkv形式のプロパティを使いたいなら、wrangler.tomlで
varsセクションを使えばよいです。
[vars] FOO = "bar"
Env経由でKeyを指定すれば値が取得できます。
use worker::*; #[event(fetch)] pub async fn main(mut req: Request, env: Env, _ctx: Context) -> Result<Response> { let vars_value = env.var("FOO")?.to_string(); let response_body = format!("vars_value:{}",vars_value); Response::ok(response_body) }
secretを使う
パスワードやトークンなどの機密性が高いデータはsecretをつかいます。
# my_secretに値を設定 % npx wrangler secret put my_secret
use worker::*; #[event(fetch)] pub async fn main(mut req: Request, env: Env, _ctx: Context) -> Result<Response> { let my_secret = env.secret("my_secret")?.to_string(); let response_body = format!("my_secret:{}",my_secret); Response::ok(response_body) }
ローカルで動かしたい場合、 .dev.varsファイルをルートに作成し、↓のように記述しておきます。
my_kmy_secretey=local_secret_value
Json形式のファイルを使う
シンプルなデータであればkey=value形式でよいのですが、
もう少し複雑なデータ形式を扱いたい場合もあります。
Cloudflare Workers KVを使えば複雑な形式のデータも扱えますが、
面倒なので、マクロをつかってそれっぽく使えるようにします。
まずはルートにexample.jsonファイルを作成します。
{ "key" : "bar", "value":"buzz" }
Cargo.tomlにcrateを追加します。
[dependencies] once_cell = "1.19.0" serde = "1.0.195" serde_json = "1.0.111" ・・・
↑もしくはaddコマンドで追加。
% cargo add once_cell serde serde_json
Workersのコードです。
include_str!マクロでjsonファイルを展開し、
serdeでJSONオブジェクトに変換しています。
また、何度も処理が実行されないように
once_cellをつかっています。
use serde::{Deserialize, Serialize}; use worker::*; use once_cell::sync::Lazy; static CONFIG_JSON: Lazy<JsonData> = Lazy::new(|| { let example_json_str = include_str!("../example.json"); serde_json::from_str(example_json_str).expect("JSON was not well-formatted") }); #[derive(Serialize, Deserialize,Debug)] struct JsonData { key: String, value: String, } #[event(fetch)] pub async fn main(mut req: Request, env: Env, _ctx: Context) -> Result<Response> { let config = &*CONFIG_JSON; //console_log!("key:{}",config.key); //console_log!("value:{}",config.value); let response_body = format!("config:{:?}",config); Response::ok(response_body) }
include_str!マクロはコンパイル時にファイルの内容を
文字列リテラルとしてプログラムに埋め込みます。
そのため、当然ながらファイルの内容は実行時には変更できません。
また、JSONファイルが大きい場合はプログラムサイズも大きくなります。
serdeによるJSONのパースは実行時に行われるため、
不正なJSONである場合は実行時エラーになるので注意してください。
Summary
Cloudflare Workersでプロパティデータにアクセスする
いくつかの方法について紹介しました。
制限はありますが、簡単にJSONファイル内容にreadアクセスしたいなら
include_str!マクロを使うのが楽かと思います。